package com.spicdt.edge.protocol.door.demo.handler;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.spicdt.edge.protocol.door.demo.conf.DoorConf;

import com.spicdt.edge.protocol.door.demo.model.ProtocolAuthInfo;
import com.spicdt.edge.protocol.door.demo.model.ProtocolPersonInfo;
import com.spicdt.edge.protocol.door.demo.model.dto.*;
import com.spicdt.edge.protocol.door.demo.model.po.Staff;
import com.spicdt.edge.protocol.door.demo.model.po.StaffDoorAccess;
import com.spicdt.edge.protocol.door.demo.service.DoorBaseService;
import com.spicdt.iedge.psdk.EdgeService;
import com.spicdt.iedge.psdk.data.CommandData;
import com.spicdt.iedge.psdk.data.CommandResponse;
import com.spicdt.iedge.psdk.data.Response;
import com.spicdt.iedge.psdk.handler.CommandHandler;
import com.spicdt.iedge.psdk.meta.DeviceCmdConstraint;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.Map;


@Slf4j
public class DoorCommandHandler implements CommandHandler {

    private final EdgeService edgeService;
    private final DoorBaseService doorBaseService;
    private final DoorConf config;
    private final Map<String, String> platformToDeviceCodeMap;

    public DoorCommandHandler(DoorBaseService doorBaseService, EdgeService edgeService,
                              DoorConf config, Map<String, String> platformToDeviceCodeMap) {
        this.doorBaseService = doorBaseService;
        this.edgeService = edgeService;
        this.config = config;
        this.platformToDeviceCodeMap = platformToDeviceCodeMap;
    }

    @Override
    public void onCommand(String deviceKey, CommandData commandData) {
        log.info("【门禁指令处理器】接收到指令：deviceKey={}, 方法={}, 参数={}",
            deviceKey, commandData.getMethod(), commandData.getParams());

        CommandResponse response = new CommandResponse();
        Response results;

        try {
            if (ObjectUtil.isEmpty(deviceKey)) {
                throw new IllegalArgumentException("设备标识 deviceKey 不能为空");
            }

            JSONObject params = JSON.parseObject(commandData.getParams(), JSONObject.class);
            if (!params.containsKey("deviceCode") || ObjectUtil.isEmpty(params.getString("deviceCode"))) {
                params.put("deviceCode", deviceKey);
                log.warn("【参数补全】未指定 deviceCode，自动使用 deviceKey 补全为：{}", deviceKey);
            }

            switch (commandData.getMethod()) {
                case DeviceCmdConstraint.DOOR_ADDPERSON:
                    results = handleAddPerson(params);
                    break;
                case DeviceCmdConstraint.DEVICE_ADD_GRANT:
                    results = handleAddGrant(params);
                    break;
                case DeviceCmdConstraint.DOOR_doorAccess:
                    results = handleDoorAccess(params);
                    break;
                case DeviceCmdConstraint.DOOR_QUERY_PERSONLIST:
                    results = doorBaseService.getStaffInfo(new UserQueryDTO());
                    break;
                default:
                    log.warn("【门禁指令处理器】不支持的指令类型：{}", commandData.getMethod());
                    results = Response.fail("500", "未知指令类型：" + commandData.getMethod(), null);
                    break;
            }

        } catch (Exception e) {
            log.error("【门禁指令处理器】指令执行异常：设备={}, 方法={}, 异常={}",
                deviceKey, commandData.getMethod(), e.getMessage(), e);
            results = Response.fail("500", e.getMessage(), null);
        }

        response.setData(JSONObject.toJSONString(results));
        response.setDeviceKey(deviceKey);
        response.setRequestId(commandData.getRequestId());

        log.info("【门禁指令处理器】处理完成，返回结果：{}", JSONObject.toJSONString(results));

        edgeService.deviceCommandResponse(response);
    }



    /**
     * 处理控制指令
     */
    private Response handleDoorAccess(JSONObject params) {
        log.info("【控制下发】参数：{}", params.toJSONString());
        DeviceRemoteControlDTO deviceRemoteControlDTO = new DeviceRemoteControlDTO();
        String deviceCode = platformToDeviceCodeMap.get(params.get("deviceCode"));
        String[] split = deviceCode.split("}--}");
        String controllerId=split[0];
        String doorId=split[1];
        deviceRemoteControlDTO.setDoorID(doorId);
        if ("1".equals(params.get("controlType").toString())){
            deviceRemoteControlDTO.setRemoteAction("off");
        }else{
            deviceRemoteControlDTO.setRemoteAction("on");
        }

        deviceRemoteControlDTO.setControllerID(controllerId);
        return doorBaseService.remoteControl(deviceRemoteControlDTO);

    }

    /**
     * 处理新增人员指令
     */
    private Response handleAddPerson(JSONObject params) {
        log.info("【新增人员】参数：{}", params.toJSONString());

        ProtocolPersonInfo personInfo = JSONUtil.toBean(params.toJSONString(), ProtocolPersonInfo.class);
        log.info("【新增人员】协议对象转换完成：{}", personInfo);

        Staff staff = convertToStaff(personInfo);
        log.info("【新增人员】转换为内部员工对象：{}", staff);

        StaffInfoDTO staffInfoDTO = new StaffInfoDTO();
        staffInfoDTO.setStaff(Collections.singletonList(staff));

        Response response = doorBaseService.addStaffInfo(staffInfoDTO);
        log.info("【新增人员】第三方接口响应：{}", response);
        return response;
    }

    /**
     * 处理新增门权限授权指令
     */
    private Response handleAddGrant(JSONObject params) {
        log.info("【门禁授权】参数：{}", params.toJSONString());

        ProtocolAuthInfo authInfo = JSONUtil.toBean(params.toJSONString(), ProtocolAuthInfo.class);
        log.info("【门禁授权】协议对象转换完成：{}", authInfo);

        StaffDTO staffDTO = new StaffDTO();
        staffDTO.setStaffID(authInfo.getObjectCode());

        String doorId = platformToDeviceCodeMap.get(authInfo.getDeviceCode());
        log.info("【门禁授权】设备编码映射：平台设备码={} → 南向门禁ID={}", authInfo.getDeviceCode(), doorId);

        StaffDoorAccess staffDoorAccess = new StaffDoorAccess();
        staffDoorAccess.setDoorID(doorId);

        EditAccessByDoorsDTO dto = new EditAccessByDoorsDTO();
        dto.setStaff(Collections.singletonList(staffDTO));
        dto.setStaffDoorAccesses(Collections.singletonList(staffDoorAccess));

        Response response = doorBaseService.editDoorPermission(dto);
        log.info("【门禁授权】第三方接口响应：{}", response);
        return response;
    }

    /**
     * 协议人员信息转为内部员工结构
     */
    public Staff convertToStaff(ProtocolPersonInfo info) {
        Staff staff = new Staff();

        staff.setStaffID(info.getPersonId());
        staff.setStaffName(info.getPersonName());
        staff.setStaffFirstName(info.getPersonName()); // 没有拆分字段则临时使用姓名
        staff.setStaffLastName(""); // 无法提取
        staff.setOldStaffID(info.getAuthenticateCode());
        staff.setUserGroup(info.getRoleName());
        staff.setStaffPhoto(info.getFile());

        if ("M".equalsIgnoreCase(info.getGender())) {
            staff.setGender("1");
        } else if ("F".equalsIgnoreCase(info.getGender())) {
            staff.setGender("2");
        }

        // 默认设置项
        staff.setVisitor("0");
        staff.setIsPhotoforFR("1".equals(info.getAuthenticateType()) ? "1" : "0");
        staff.setReplace("0");
        staff.setAccessRightBinding("noBinding");
        staff.setAccessTemplate("");

        return staff;
    }
}




